using System;
using System.Collections.Generic;
using ViScript.Core.Argument;
using ViScript.Core.Arguments;
using ViScript.Core.Exceptions;

namespace ViScript.Core.ParsedSentence
{
    public class NormalParsedSentence : IParsedSentence
    {
        private readonly ISentence sentence;
        private readonly ISentenceRule sentenceRule;
        private readonly IArguments arguments;

        public NormalParsedSentence(ISentence sentence, ISentenceRule sentenceRule, IArguments arguments)
        {
            this.sentence = sentence;
            this.sentenceRule = sentenceRule;
            this.arguments = arguments;
        }

        public bool IsValid
        {
            get { return arguments.IsValid; }
        }

        public ISentence Sentence
        {
            get { return sentence; }
        }


        public ISentenceRule SentenceRule
        {
            get { return sentenceRule; }
        }

        public IArguments Arguments
        {
            get { return arguments; }
        }

        public void Execute()
        {
            try
            {
                sentenceRule.Execute(EvaluateArguments(arguments.Value));
            }
            catch (Exception ex)
            {
                throw new ViScriptExecutionException(sentence, ex);
            }
        }

        public void Accept(IParsedSentenceVisitor visitor)
        {
            visitor.VisitNormal(this);
        }

        public virtual object[] EvaluateArguments(IArgument[] args)
        {
            List<object> evaluatedArgs = new List<object>();
            foreach (IArgument arg in args)
            {
                evaluatedArgs.Add(arg.Value);
            }
            return evaluatedArgs.ToArray();
        }
    }
}